import { useCallback, useEffect, useState } from 'react';

export type CDNOptions = {
  /** cdn裁剪模式 */
  mode?: number;
  /** 图片倍率 */
  magnify?: number;
  /** 图片质量[0-100] */
  quality?: number;
};

type CDNProps = {
  /** 裁剪宽 */
  width?: string | number;
  /** 裁剪高 */
  height?: string | number;
  /** 原图片地址 */
  src?: string;
  /** cdn选项 */
  options?: CDNOptions;
  /** cdn开关 */
  open?: boolean;
};

const check_webp_feature = (feature: any, callback: any) => {
  const kTestImages: any = {
    lossy: 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA',
    lossless: 'UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==',
    alpha:
      'UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==',
    animation:
      'UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA',
  };
  const img = new Image();
  img.onload = function () {
    const result = img.width > 0 && img.height > 0;
    callback(feature, result);
  };
  img.onerror = function () {
    callback(feature, false);
  };
  img.src = 'data:image/webp;base64,' + kTestImages[feature];
};

const checkPromise = () =>
  new Promise((reslove) => {
    check_webp_feature('lossy', function (feature: any, isSupported: any) {
      if (isSupported) {
        reslove(true);
      } else {
        reslove(false);
      }
    });
  });

const spliceLastFlag = (url: string) => {
  const length = url.length;
  if (url.slice(length - 1) === '|') {
    url = url.slice(0, length - 1);
  }
  return url;
};

export const useCDN = ({
  width,
  height,
  src,
  options = {},
  open = false,
}: CDNProps) => {
  const [cdnSrc, setCdnSrc] = useState<any>(undefined);
  const [feature, setFeature] = useState({
    isImage2: false,
    isPiple: false,
    lastFlag: false,
    url: '',
  });

  const resetUrl = useCallback((url: any) => {
    if (!url) return '';
    let isImage2 = false;
    let isPiple = false;
    let lastFlag = false;
    if (url.indexOf('imageView2/') !== -1) {
      isImage2 = true;
    }
    if (url.indexOf('watermark/') !== -1 || url.indexOf('imageMogr2') !== -1) {
      isPiple = true;
    }
    const length = url.length;
    if (url.slice(length - 1) === '|') {
      lastFlag = true;
    }
    setFeature({
      isImage2,
      isPiple,
      lastFlag,
      url: url.indexOf('?') > -1 ? url : `${url}?`,
    });
  }, []);

  const handleImageView2 = useCallback(
    async (url = '') => {
      const { mode, w, h, q } = getSearchs();
      const webp = await handleWebp();
      const params = `${
        feature.isPiple && !feature.lastFlag ? '|' : ''
      }imageView2/${mode}/w/${w}/h/${h}/q/${q}/format/${webp}`;
      setCdnSrc(spliceLastFlag(`${url}${params}` as any));
    },
    [feature],
  );

  const handleReplace = useCallback(async (url = '') => {
    const { w, h, q, mode } = getSearchs();
    const webp = await handleWebp();
    // /imageView2(.*\||.*)/
    const parmas = `imageView2/${mode}/w/${w}/h/${h}/q/${q}/format/${webp}`;
    const regex = /imageView2.*/;
    const regexWithFlag = /imageView2.*\|/;
    if (regexWithFlag.test(url)) {
      url = url.replace(regexWithFlag, `${parmas}|`);
    } else {
      url = url.replace(regex, `${parmas}`);
    }
    setCdnSrc(spliceLastFlag(url as any));
  }, []);

  const handleWebp = useCallback(async () => {
    const supporWebp = await checkPromise();
    return supporWebp ? 'webp' : '';
  }, []);

  const getSearchs = useCallback(() => {
    const mode = options?.mode || 2;
    const magnify = options?.magnify || 3;
    const quality = options?.quality || 75;
    return {
      mode,
      w: width ? (Number(width) * magnify)?.toFixed?.(0) : 0,
      h: height ? (Number(height) * magnify)?.toFixed?.(0) : 0,
      q: quality,
    };
  }, [width, height, options]);

  useEffect(() => {
    open && src && resetUrl(src);
  }, [src, open]);

  useEffect(() => {
    if (src && open) {
      if (feature.isImage2) {
        feature.url && handleReplace(feature.url);
      } else {
        feature.url && handleImageView2(feature.url);
      }
    }
  }, [src, width, height, feature, open]);

  // useEffect(() => console.log("#cdn src#", cdnSrc), [cdnSrc]);

  return [cdnSrc];
};
